import { ACTOR_TYPE, BActor, VTActor, VTActorOptions } from "cax-base";
import vtkPoints from "@kitware/vtk.js/Common/Core/Points";
import vtkCellArray from "@kitware/vtk.js/Common/Core/CellArray";
import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
import vtkActor from "@kitware/vtk.js/Rendering/Core/Actor";
import vtkMapper from "@kitware/vtk.js/Rendering/Core/Mapper";
import vtkAppendPolyData from "@kitware/vtk.js/Filters/General/AppendPolyData";

export class MeshThicknessActor extends BActor {
  instance: vtkActor = vtkActor.newInstance();
  readonly type = ACTOR_TYPE.GRAPHIC_ACTOR;
  createdBy = "default";
  pointsData: number[][][];
  thickness: number;
  constructor(pointsData: number[][][], thickness: number) {
    super();
    this.pointsData = pointsData;
    this.thickness = thickness / 2;
    const appendFilter = this.createSolidsFromMidFaces(pointsData, thickness);
    // 创建Mapper和Actor
    const mapper = vtkMapper.newInstance();
    // mapper.setInputData(ployData);
    mapper.setInputConnection(appendFilter.getOutputPort());

    this.instance.setMapper(mapper);
    this.instance.getProperty().setColor(1.0, 0.0, 0.0); // 设置颜色
    this.instance.getProperty().setEdgeVisibility(true);
  }
  createSolidsFromMidFaces(
    midFaces: number[][][],
    totalThickness = 24
  ): vtkAppendPolyData {
    // 参数校验
    // if (!Array.isArray(midFaces) || midFaces.length === 0) {
    //   throw new Error("需要至少一个中面数据");
    // }
    const appendFilter = vtkAppendPolyData.newInstance();

    midFaces.forEach((face, i) => {
      const solid = this.createPrismFromPolygon(face, totalThickness);
      appendFilter.addInputData(solid);
    });
    // 2. 更新并返回合并后的数据
    appendFilter.update();
    return appendFilter;
  }
  createPrismFromPolygon(
    basePoints: number[][],
    thickness = 24,
    normal?: number[]
  ): vtkPolyData {
    // 参数校验
    // if (basePoints.length < 3 || basePoints.some((pt) => pt.length !== 3)) {
    //   throw new Error("至少需要3个三维点坐标");
    // }

    const points = vtkPoints.newInstance();
    const polys = vtkCellArray.newInstance();
    const vertexCount = basePoints.length;

    // 1. 计算法线（若未提供）
    const computedNormal = normal || this.computePolygonNormal(basePoints);
    const unitNormal = this.normalizeVector(computedNormal);

    // 2. 生成顶点（底面 + 顶面）
    const allPoints: number[] = [];

    // 底面顶点
    // basePoints.forEach((pt) => allPoints.push(...pt));
    basePoints.forEach((pt) => {
      allPoints.push(
        pt[0] - unitNormal[0] * thickness,
        pt[1] - unitNormal[1] * thickness,
        pt[2] - unitNormal[2] * thickness
      );
    });

    // 顶面顶点（沿法线偏移）
    basePoints.forEach((pt) => {
      allPoints.push(
        pt[0] + unitNormal[0] * thickness,
        pt[1] + unitNormal[1] * thickness,
        pt[2] + unitNormal[2] * thickness
      );
    });

    points.setData(Float32Array.from(allPoints));

    // 3. 创建底面多边形
    const basePolygon = Array.from({ length: vertexCount }, (_, i) => i);
    polys.insertNextCell(basePolygon);

    // 4. 创建顶面多边形（反转顺序）
    const topPolygon = Array.from(
      { length: vertexCount },
      (_, i) => vertexCount + i
    ).reverse();
    polys.insertNextCell(topPolygon);

    // 5. 创建侧面四边形
    for (let i = 0; i < vertexCount; i++) {
      const nextIdx = (i + 1) % vertexCount;
      polys.insertNextCell([
        i, // 当前底面点
        nextIdx, // 下一个底面点
        vertexCount + nextIdx, // 下一个顶面点
        vertexCount + i, // 当前顶面点
      ]);
    }

    const prism = vtkPolyData.newInstance();
    prism.setPoints(points);
    prism.setPolys(polys);

    return prism;
  }
  // 计算多边形法线（新加辅助函数）
  computePolygonNormal(points: number[][]): number[] {
    const normal = [0, 0, 0];
    for (let i = 0; i < points.length; i++) {
      const curr = points[i];
      const next = points[(i + 1) % points.length];
      normal[0] += (curr[1] - next[1]) * (curr[2] + next[2]);
      normal[1] += (curr[2] - next[2]) * (curr[0] + next[0]);
      normal[2] += (curr[0] - next[0]) * (curr[1] + next[1]);
    }
    return normal;
  }

  // 向量归一化（新加辅助函数）
  normalizeVector(v: number[]): number[] {
    const length = Math.sqrt(v.reduce((sum, n) => sum + n * n, 0));
    return length > 0 ? v.map((n) => n / length) : [0, 0, 1]; // 默认Z轴
  }
}
